package Page
{
	/*
/uploadsfolder (mine is C:\DP\uploads )
    /25xxx (the directory we download the raw images into)
        /25xxx (you create this one, and the next one too)
            /25xxx-page-images (this contains your output files)
    /25xxy (same deal, next project)
        /25xxy
            /25xxy-page-images
	*/
	
	import Regex.Regex;
	
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
    
    [Bindable]
	public class PageSet extends ArrayCollection
	{
	    private static const PAGE_MAP_FILE_NAME:String = "pagemap";
		private var _dir:File;
		private var _words:Object;
		private var _word_count:int;
		private var _unique_word_count:int;
		
		public function PageSet(dir:File, charset:String)
		{
            _dir = dir;
            loadPages(charset);
            if(this.length <= 0) {
                Alert.show("No image files found in " + this.path);
                return;
            }
            
            var ifa:Object = loadMap();
            if( ifa ) 
            {
                var o:Object;
                for each(var p:Page in this)
                {
                    o = ifa[p.name];
                    if( o )
                    {
                        p.species = o.species;
                        p.remark = o.remark;
                        p.section = o.section;
                        p.pageNumber = o.pageNumber ? o.pageNumber.toString() : ""; 
                    }
                }
            }
		}
		
        private static function buildPath(p1:String, p2:String):String {
            for( ; p1.length > 0 && ( p1.substr(-1) === "\\" || p1.substr(-1) === "/"); ) {
                p1 = p1.substr(0, p1.length-1);
            }
            for( ; p2.length > 0 && ( p2.substr(0, 1) === "\\" || p2.substr(0, 1) === "/"); ) {
                p2 = p2.substr(1);
            }
            return p1 + "/" + p2;
        }
        
		public function get Text():String {
		    var _text:String;
		    if(_text.length == 0) {
    		    for each(var fi:Page in this) {
    		        _text += fi.Text;
    		    }
    		}
    		return _text;
		}
		
        private function get mapFile():File {
        	var s:String = buildPath(_dir.nativePath, PAGE_MAP_FILE_NAME);
        	return _dir.resolvePath(s);
        }
        
        public function saveMap():void {
            if(this.length === 0) {
            	return;
            }
            var a:Object = new Object;
            var i:Page;
            for each(i in this) {
                var b:Object = new Object;
                b["section"] = i.section;
                b["remark"] = i.remark;
                b["species"] = i.species;
                b["pageNumber"] = i.pageNumber;
                a[i.name] = b;
            }
            var s:FileStream = new FileStream();
            s.open(mapFile, FileMode.WRITE);
            try {
                s.writeObject(a);
            } catch(e:Error) {
                Alert.show(e.message, "Map file write failed");
            }
            s.close()
        }
        
       public function loadMap():Object {
            if(! mapFile.exists) {
                return null;
            }
            var ary:Object;
            var s:FileStream = new FileStream();
            s.open(mapFile, FileMode.READ);
            try {
                ary = s.readObject();
            }
            catch(e:Error) {
                s.close();
                Alert.show(e.message, "Map file load failed");
                return null;
            }
            s.close();
            return ary;
        }
        
        public function getPageByName(str:String):Page {
            var o:Object;
            for each(o in this) {
            	if(o.name == str) {
            		return Page (o);
            	}
            }	
            return null;
        }
        
        public function dehyphenatePages(): void {
            for each(var p:Page in this.Pages) {
                p.dehyphenate();
            }    
        }
        
        public function get FirstPage():Page {
            if(length > 0) {
                return this.getPage(0);
            } else
                return null;
        }
        
        public function get LastPage():Page {
            if(this.length > 0) {
                return this.getPage(this.length-1);
            } else
                return null;
        }
                
        private function mapPage(o:Object):void {
        	var f:Page = this.getPageByName(o.name);
        	if(f) {
        		f.section = o.section;
        		f.pageNumber = o.pageNumber;
        		f.species = o.species;
        		f.remark = o.remark;
        	}
        }
        
        public function getPage(idx:int):Page {
        	return this.getItemAt(idx) as Page;
        }
        
        public function get Pages():ArrayCollection {
        	return this;
        }
        
        public function getPageIndex(pg:Page):uint {
            return this.getItemIndex(pg);
        }
        
        public function get path():String {
        	return _dir.nativePath;
        }
        
        public function clearSections():void {
        	for(var i:Number = 0; i < length; i++) {
                this.getPage(i).section = "";
            }
        }
        public function clearPageNumbers():void {
            for(var i:Number = 0; i < length; i++) {
                this.getPage(i).pageNumber = "";
            }
        }
        public function clearSpecies():void {
            for(var i:Number = 0; i < length; i++) {
                this.getPage(i).species = "";
            }
        }
        public function clearRemarks():void {
            for(var i:Number = 0; i < length; i++) {
                this.getPage(i).remark = "";
            }
        }
        
        private function loadPages(charset:String):void {
	        var flist:Array = _dir.getDirectoryListing();
	        this.removeAll();
	
            for each(var f:File in flist) {
               if(f.extension === "png" || f.extension === "jpg"
                   || f.extension === "bmp" || f.extension === "tiff"
                   || f.extension === "tif") {
                   var fi:Page = new Page(this.length, f, charset);
                   addItem(fi);
               }
            }
        }
        
        public function ReplaceAll(re:Regex):void {
            var f:String = re.Flags;
            if(f.indexOf("g") < 0) {
                f += "g";
            }
            var r:RegExp  = new RegExp(re.PatternString, f);
            for each(var pg:Page in this) {
                pg.Text = pg.Text.replace(r, re.ReplacePattern);
            }    
        }   
             
        public function Clear():void {
            for(var i:uint=0; i < length; i++) {
                var r:Page = getPage(i);
                r.clear();
            }
        }

        public function RefreshWordsObject():void {
            this._init_words();    
        }
        
        private function _init_words():void {
            var o:Object = new Object();
            var wc:int = 0;
            var uwc:int = 0;
            var _pgwds:Array;
            
            this._words = new Object();

            for each(var pg:Page in this) {
                _pgwds = pg.WordsArray;
                
                // _gwds is an array
                for each(var w:String in _pgwds) {
                    wc++;
                    if( ! _words[w] ) {
                        uwc++;
                        var o0:Object = new Object();
                        o0["key"] = w;
                        o0["count"] = 1;
                        _words[w] = o0;
                    }
                    else {
                        _words[w]["count"]++ 
                    }
                } 
            }
            this._unique_word_count = uwc;
            this._word_count = wc;
        }   
             
        public function get WordsObject():Object {
            if(! _words) {
                this._init_words();
            }
            return _words;
        }
        
        public function IsWordObject( word:String ):Boolean {
            return this.WordsObject[word] as Boolean;
        }
        
        public function get WordCount():int {
            return this._word_count;
        }
        
        public function get UniqueWordCount():int {
            return this._unique_word_count;
        }
        
        public function get HyphenatedWords():Array {
            var w:String;
            var aret:Array = new Array();
            for each( var o:Object in this.WordsObject ) {
                w = o.key as String;
//                if( w.search( /\w\-\*/ ) >= 0 ) {
                if( w.search( Twister.gContext.WORD_EXTENDED_PLUS_HYPHEN_REGEX ) >= 0 ) {

                    var o1:Object = {key:o.key, count:o.count} ;
                    aret.push(o1);
                }
            }
            return aret;
        }
        
        public function getTextInstances( pre:RegExp ):Array {
            var a:Array = new Array();

            for each( var pg:Page in this ) {
                var tis:Array = pg.getTextInstances( pre );
                a = a.concat( tis );
            }
            return a;
        }
        
//        public function get deAccentedWords():ArrayCollection {
//            var re:RegExp = new RegExp(_accents, "g");
//            if(! _deaccented_words) {
//                for each(var word:String in words) {
//                    if(word.search(_accents)) {
//                        var dword:String;
//                        var m:Object;
//                        while(m = re.exec(word)) {
//                            dword = word.substr(0, m.index) + _accent_map[m[0]] + word.substr(m.index+1);
//                        }
//                        _deaccented_words[word] = dword;
//                    }   
//                }            
//            }
//            return _deaccented_words;
//        }
    } 
}    

